package cn.tenghw.redission.controller;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * Created by IntelliJ IDEA2021.3
 * @Author: Tenghw
 * @Date: 2022/11/10  12:06
 * @Description:
 */
@SuppressWarnings("all")
@RestController
public class RedissionController {
    /**
     * 这2个注入，是根据name来找的，而不是根据类型，所以用@Resource，而不是用Autowired
     */
    @Resource
    private Redisson redisson;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    @RequestMapping("delete_stock")
    public String deleteStock(){
        //0.标识符
        String clientID = UUID.randomUUID().toString();
        //1.这个相当于一把锁，控制某个时间段只能一个人来
        String lockKey="product001";
        RLock lock = redisson.getLock(lockKey);

        try {
            //// 2.获取锁
            Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "银鹭八宝粥");// key必须不存在，等价于jedis.setnx(key, value);
            //// 3.如果突发宕机，锁没有释放掉怎么办，设置key过期处理(10s)，但是如果在获取锁之后就出问题呢，这一步也没有成功，大招：二合一
            //stringRedisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);


            // 2-3
/*          Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientID, 10, TimeUnit.SECONDS);
            if (!result){
                return "error";
            }
*/

            // 3.1 解决过期时间内还未完成操作的问题
            lock.lock(30, TimeUnit.SECONDS); // 先拿锁，再设置超时时间

            // 4.真正操作商品库存
            synchronized (this){
                int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock")); // jedis.get("stock");
                if (stock > 0){
                    int realStock = stock - 1;
                    stringRedisTemplate.opsForValue().set("stock", realStock + ""); // jedis.set(key, value);
                    System.out.println("扣减成功，剩余库存：" + realStock);
                }else {
                    System.out.println("扣减失败，库存不足！");
                }
            }
        }finally {
            lock.unlock(); // 释放锁
/*
            if (clientID.equals(stringRedisTemplate.opsForValue().get(lockKey))) {
                // 5.释放锁，放在finally块中防止没有释放锁导致死锁问题
                stringRedisTemplate.delete(lockKey);
            }
*/
        }
        return "end";

    }
}
